/*************
author:: libo
license:: MIT
*****************/
#ifndef LIBCELL_MESH_IO_H
#define LIBCELL_MESH_IO_H
#include<stdio.h>
#include<Mesh/_Func_.h>
#include<string.h>
#define _ReadOff_   LibCell_ReadOff_
#define _ReadCell_  LibCell_ReadCell_
#define _WriteCell_ LibCell_WriteCell_
#define _WriteOff_ LibCell_WriteOff_
#define _ReadArray_ LibCell_ReadArray_
#define _ReadObj_ LibCell_ReadObj_
#define _ReadPly_ LibCell_ReadPly_
#define _ReadPcd_ LibCell_ReadPcd_
#define _ReadStl_ LibCell_ReadStl_

// #define iterator_v lib_cell_iterator_vertices
// #define iterator_f lib_cell_iterator_faces
// #define iterator_c lib_cell_iterator_cells
// #define quote lib_cell_quote
//#define _Read_ LibCell_Read_
/**********
***********/


#ifdef __cplusplus
extern "C"{
#endif
/**********
**********/




int _ReadOff_(template_m* ,char const * ,int);
/************
***********/
Node* _ReadM_(template_m*,char const *);


int _ReadCell_(template_m*,char const *);

int _WriteCell_(template_m*,char const *);

int _WriteOff_(template_m* m,char const *);


// F is halffaces 
// C is cells

int _ReadArray_(template_m*m,double**V,int**F,int **C,int*num,int back_dim,int manifold_dim );




char** split(char *  targetString, const char  delimiter,int *  length);


typedef struct OBJ_CELL_PROP{
    char *mtlname;
    char *group_info;
    double **vt;
    double **vn;
    int n;

}OBJ_CELL_PROP;

typedef struct OBJ_MESH_PROP{
    char *mtlibname;

}OBJ_MESH_PROP;

static inline void obj_cell_prop_init(OBJ_CELL_PROP* ofp)
{
    ofp->mtlname=NULL;
    ofp->group_info=NULL;
    ofp->vt=NULL;
    ofp->vn=NULL;
    ofp->n=0;

}
static inline void obj_cell_prop_free(OBJ_CELL_PROP*ocp)
{
    if(ocp==NULL)
    {
        return;
    }
    SAFE_FREE(ocp->mtlname);
    SAFE_FREE(ocp->group_info);
    if(ocp->vt!=NULL)
    {
        for(int i=0;i<ocp->n;i++)
        {
            SAFE_FREE(ocp->vt[i]);
        }
    }
    if(ocp->vn!=NULL)
    {
        for(int i=0;i<ocp->n;i++)
        {
            SAFE_FREE(ocp->vn[i]);
        }
    }
   
    SAFE_FREE(ocp->vt);SAFE_FREE(ocp->vn);
    free(ocp);
}



static inline void obj_mesh_prop_init(OBJ_MESH_PROP* omp)
{
    omp->mtlibname=NULL;
}
static inline void obj_mesh_prop_free(OBJ_MESH_PROP*omp)
{
    if(omp==NULL)
    {
        return;
    }
    SAFE_FREE(omp->mtlibname);
    free(omp);
}

// 读obj文件
// cell prop is occupied
int _ReadObj_(template_m* m,char const*);
void export_obj_from_node(Node* node,char* filename,char * mtlname);

typedef struct PLY_Vertex_Prop{
    unsigned char rgb[3];
    float n[3];
    void* prop;

}PLY_Vertex_Prop;



int  _ReadPly_(template_m*m,char const *);

int _ReadPcd_ (template_m* m,const char  * );


static const char * filename_suffix(const char *filename,char delimit)
{
    int len=strlen(filename);
    for(int i=1;i<len;i++)
    {
        if(filename[len-i]==delimit)
        {
            return (filename+len-i+1);
        }

    } 
    return NULL;
}

int  _ReadStl_(template_m* m,char const * );

#ifdef __cplusplus
}
#endif


// #undef iterator_v 
// #undef iterator_f 
// #undef iterator_c 
// #undef quote 
#undef _ReadOff_ 
#undef _ReadCell_
#undef _ReadObj_
#undef _WriteCell_ 
#undef _WriteOff_
#undef _ReadArray_ 
#undef _ReadPly_
#undef _ReadPcd_
#undef _ReadStl_

#endif

